package com.baiqian.doupo.network;

import com.baiqian.doupo.Utils;
import com.baiqian.doupo.capability.DouPoModCapability;
import com.baiqian.doupo.capability.douqi.IDouQiCapability;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.network.PacketDistributor;

import java.util.Objects;
import java.util.UUID;
import java.util.function.Supplier;

import static com.baiqian.doupo.KeyBoradSave.keyG;
import static com.baiqian.doupo.KeyBoradSave.keyH;

public class SendPack {

    private final CompoundNBT message;

    public SendPack(PacketBuffer buffer) {//反序列化数据包
        message = buffer.readCompoundTag();
    }

    public SendPack(int num) {
        CompoundNBT message = new CompoundNBT();
        message.putInt("send_pack_num",num);
        this.message = message;
    }

    public SendPack(int num,CompoundNBT message) {
        message.putInt("send_pack_num",num);
        this.message = message;
    }

    public SendPack(int num,UUID uuid,int keyCh) {
        CompoundNBT message=new CompoundNBT();
        message.putInt("send_pack_num",num);
        message.putUniqueId("uuid",uuid);
        message.putInt("keyCh",keyCh);
        this.message = message;
    }

    public SendPack(int num,String gui_set,int choose) {
        CompoundNBT message=new CompoundNBT();
        message.putInt("send_pack_num",num);
        message.putString("gui_set",gui_set);
        message.putDouble("choose",choose);
        this.message = message;
    }

    public SendPack(int num,String gui_set,int[] choose) {
        CompoundNBT message=new CompoundNBT();
        message.putInt("send_pack_num",num);
        message.putString("gui_set",gui_set);
        message.putIntArray("choose",choose);
        this.message = message;
    }

    public SendPack(int num,String name) {
        CompoundNBT message=new CompoundNBT();
        message.putInt("send_pack_num",num);
        message.putString("name",name);
        this.message = message;
    }

    public void toBytes(PacketBuffer buf) {//序列化数据包
        buf.writeCompoundTag(message);
    }

    public void handler(Supplier<NetworkEvent.Context> ctx) {
        //这里的ctx是用来进行线程安全操作用的
        //这个方法的作用就是在接收端接收到数据以后，如何使用这些数据。
        //请注意，你必须把这里的执行操作放在ctx.get().enqueueWork这个方法内，以闭包的形式呈现。
        //并且在执行完成后需要加上ctx.get().setPacketHandled(true);表示执行成功
        //以确保线程安全
        ctx.get().enqueueWork(() -> {
            LazyOptional<IDouQiCapability> douQiCap;
            ServerPlayerEntity serverPlayerEntity = ctx.get().getSender();
            if(serverPlayerEntity==null){//在客户端
                ClientPlayerEntity clientPlayerEntity = Minecraft.getInstance().player;
                if(clientPlayerEntity!=null) {
                    douQiCap = clientPlayerEntity.getCapability(DouPoModCapability.DOUQI_CAPABILTTY);
                    if (douQiCap.isPresent()) {
                        douQiCap.ifPresent((l) -> {
                            switch (message.getInt("send_pack_num")) {//在客户端
                                case 0:{//将服务端发送过来的玩家数据覆盖至客户端
                                    l.deserializeNBT(message);
                                    break;
                                }
                                case 1: {//服务端想请求一份数据(通常不用)
                                    Networking.INSTANCE.sendToServer(new SendPack(0,l.serializeNBT()));
                                    break;
                                }
                                case 2:{//同步玩家飞行能力
                                    //主动开关
                                    l.deserializeNBT(message);
                                    if(l.isFlying()){
                                        clientPlayerEntity.abilities.allowFlying=true;
                                        clientPlayerEntity.sendMessage(new TranslationTextComponent("message." + Utils.MOD_ID + ".press_SPACE_to_true"), clientPlayerEntity.getUniqueID());
                                    }else{
                                        clientPlayerEntity.abilities.allowFlying=false;
                                        clientPlayerEntity.abilities.isFlying=false;
                                        clientPlayerEntity.sendMessage(new TranslationTextComponent("message."+ Utils.MOD_ID+".press_SPACE_to_false"),clientPlayerEntity.getUniqueID());
                                    }
                                    break;
                                }
                            }
//                            switch (message.getInt("send_pack_num")) {
//                                case 0://获得从服务端过来的数据
//                                    l.deserializeNBT(message);
//                                    break;
//                                case 1: {//服务端想请求一份数据
//                                    Networking.INSTANCE.sendToServer(new SendPack(0,l.serializeNBT()));
//                                    break;
//                                }
//                                case 2: {
//                                    switch (message.getInt("who")){
//                                        case 0://自己
//                                            switch(message.getInt("effect")){
//                                                case 2:player.addPotionEffect(new EffectInstance(Effects.SLOWNESS, message.getInt("time"), message.getInt("width")));break;
//                                            }
//                                            break;
//                                        case 1://对方
//                                        case 2://周围
//                                    }
//                                    break;
//                                }
//                                case 3:{//处理从服务端发过来的数据列表
//                                    KeyBoradSave.effect.put(message.getUniqueId("uuid"),message.getBoolean("isKeyGPress"));
//                                    LogManager.getLogger().info("从服务端发货来的数据:"+message.getUniqueId("uuid")+" "+message.getBoolean("isKeyGPress"));
//                                    break;//获得从服务端过来的数据
//                                }
//                            }
                        });
                    }
                }
            }
            else{
                douQiCap = Objects.requireNonNull(serverPlayerEntity).getCapability(DouPoModCapability.DOUQI_CAPABILTTY);
                if (douQiCap.isPresent()) {
                    douQiCap.ifPresent((newCap) -> {//在服务端
                        switch(message.getInt("send_pack_num")) {//在服务端
                            case 0: {//将客户端发送过来的玩家数据覆盖至服务端(通常不用)
                                newCap.deserializeNBT(message);
                                break;
                            }
                            case 1: {//客户端想请求一份数据
                                Networking.INSTANCE.send(
                                        PacketDistributor.PLAYER.with(
                                                () -> serverPlayerEntity
                                        ),
                                        new SendPack(0, newCap.serializeNBT()));
                                break;
                            }
                            case 3:{//根据玩家键入的按键进行处理:按下
                                int douji_num = 3;
                                switch (message.getInt("keyCh")){
                                    case 'G':{
                                        keyG.put(message.getUniqueId("uuid"),10);
                                        break;
                                    }
                                    case 'H':{
                                        keyH.put(message.getUniqueId("uuid"),10);
                                        break;
                                    }
                                    case 'C':
                                        --douji_num;
                                    case 'V':
                                        --douji_num;
                                    case 'B':
                                        --douji_num;
                                    case 'N':
                                    {
                                        //发动斗技
                                        if (douQiCap.isPresent()) {
                                            int finalDouji_num = douji_num;
                                            douQiCap.ifPresent((l) -> {
                                                if(l.getDouJiGroup()[l.getDouJiGroupChoose()*4+ finalDouji_num]!=-1) {
                                                    l.getDouJis().get(l.getDouJiGroup()[l.getDouJiGroupChoose() * 4 +finalDouji_num]).start_use_time(l,serverPlayerEntity);
                                                }
                                            });
                                        }
                                        break;
                                    }
                                    case '↑':{
                                        newCap.addDouQiReleasePercentage();
                                        break;
                                    }
                                    case '↓':{
                                        newCap.loseDouQiReleasePercentage();
                                        break;
                                    }
                                    case ' ':{
                                        newCap.isFlying(!newCap.isFlying());
                                        //主动开关
                                        if(newCap.isFlying()){
                                            serverPlayerEntity.abilities.allowFlying=true;
                                        }else{
                                            serverPlayerEntity.abilities.allowFlying=false;
                                            serverPlayerEntity.abilities.isFlying=false;
                                        }
                                Networking.INSTANCE.send(
                                        PacketDistributor.PLAYER.with(
                                                () -> ctx.get().getSender()
                                        ),
                                        new SendPack(2,newCap.serializeNBT()));
                                        break;
                                    }
                                }
                                break;
                            }
                            case 4:{//根据玩家键入的按键进行处理:松开
                                switch (message.getInt("keyCh")){
                                    case 'G':{
                                        keyG.put(message.getUniqueId("uuid"),0);
                                        break;
                                    }
                                    case 'H':{
                                        keyH.put(message.getUniqueId("uuid"),0);
                                        break;
                                    }
                                }
                                break;
                            }
                            case 5:{//未使用
                                break;
                            }
                            case 6:{//功法和斗技的界面设置处理
                                switch (message.getString("gui_set")){
                                    case "gongfa":{
                                        newCap.setGongFaChoose(message.getInt("choose"));
                                        break;
                                    }
                                    case "douji":{
                                        newCap.setDouJiGroup(message.getIntArray("choose"));
                                        break;
                                    }
                                }
                                break;
                            }
                            case 7:{//未使用
                                break;
                            }
                            case 8:{//键盘左右键
                                switch (message.getString("name")){
                                    case "left":
                                        newCap.setDouJiGroupChoose(newCap.getDouJiGroupChoose() - 1);
                                        break;
                                    case "right":
                                        newCap.setDouJiGroupChoose(newCap.getDouJiGroupChoose() + 1);
                                        break;
                                }
                                break;
                            }
                        }
//                        switch(message.getInt("send_pack_num")){
//                            case 0:
//                                newCap.deserializeNBT(message);
//                            break;//获得从客户端过来的数据
//                            case 1:{//客户端想请求一份数据
//                                Networking.INSTANCE.send(
//                                        PacketDistributor.PLAYER.with(
//                                                () -> ctx.get().getSender()
//                                        ),
//                                        new SendPack(0,newCap.serializeNBT()));
//                                break;
//                            }
//                            case 2: {//添加效果
//                                switch (message.getInt("who")){
//                                    case 0://自己
//                                        switch(message.getInt("effect")){
//                                            case 2:Objects.requireNonNull(ctx.get().getSender()).addPotionEffect(new EffectInstance(Effects.SLOWNESS, message.getInt("time"), message.getInt("width")));break;
//                                        }
//                                        break;
//                                    case 1://对方
//                                    case 2://周围
//                                }
//                                break;
//                            }
//                            case 3:{
//                                KeyBoradSave.effect.put(message.getUniqueId("uuid"),message.getBoolean("isKeyGPress"));
//                                for(Enumeration<UUID> uuid = KeyBoradSave.effect.keys(); uuid.hasMoreElements();){
//                                    UUID uid = uuid.nextElement();
//                                    for (PlayerEntity playerEntity: ctx.get().getSender().world.getPlayers()) {
//                                        Networking.INSTANCE.send(
//                                                PacketDistributor.PLAYER.with(
//                                                        () -> (ServerPlayerEntity) playerEntity
//                                                ),
//                                                new SendPack(3,uid,KeyBoradSave.effect.get(uid)));
//                                    }
//                                }
//                                break;//获得从客户端过来的数据
//                            }
//                            case 4:{//生成实体
//                                //若斗技有产出实体，则此处产生实体
//                                if(ctx.get().getSender().world.isRemote){
//                                    LogManager.getLogger().info("客户端");
//                                }else{
//                                    LogManager.getLogger().info("服务端");
//                                }
//                                DouJiShiShanLieEntity lvt_4_1_ = EntityTypeRegistry.doujiKuangShiNuGangEntity.get().create(ctx.get().getSender().world);
//                                PlayerEntity playerEntity = ctx.get().getSender();
//                                lvt_4_1_.setShooter(playerEntity);
//                                lvt_4_1_.setLocationAndAngles(
//                                        playerEntity.getPosX()+1*Math.sin(-Math.toRadians(playerEntity.rotationYaw)),
//                                        playerEntity.getPosYEye()-1+1*Math.sin(-Math.toRadians(playerEntity.rotationPitch)),
//                                        playerEntity.getPosZ()+1*Math.cos(-Math.toRadians(playerEntity.rotationYaw)),
//                                        playerEntity.rotationYaw, playerEntity.rotationPitch);
//                                ctx.get().getSender().world.addEntity(lvt_4_1_);
//                                break;
//                            }
//                            case 5:{
//                                break;
//                            }
//                        }
                    });
                }
            }
        });
        ctx.get().setPacketHandled(true);
    }
}

